﻿using System;
using System.Data;
using capaDatos;

namespace accesoDatos
{
    public class ManejadorBD
    {
        /* --------------------- Atributos de la clase --------------------- */
        private BaseDatos baseDatos;
        private int cantResultado, ultimoIdGenerado;
        private String error;
        private const String consultaCamposDefault = "*", cadenaSQLvacia = "La consulta SQL generada está vacía.";


        /* ----------------------- Propiedades de la clase ----------------------- */
        public String Error
        {
            get { return error; }
        }

        public int CantResultado
        {
            get { return cantResultado; }
        }

        public int UltimoIdGenerado
        {
            get { return ultimoIdGenerado; }
        }

        public static string getMotorBD()
        {
            return BaseDatos.getMotorBD();
        }

        /* ------------------- Constructor ------------------- */
        public ManejadorBD()
        {
            this.baseDatos = new BaseDatos();
            this.error = this.baseDatos.getError();
            this.cantResultado = 0;
            this.ultimoIdGenerado = 0;
        }


        /* ------------------- Métodos de acceso público ------------------- */
        public int obtenerNumeroEntero(String consultaSQL)
        {
            int numero = 0;
            this.error = "";

            if (!consultaSQL.Trim().Equals(""))
            {
                numero = this.baseDatos.obtenerNumeroEntero(consultaSQL);
                this.error = this.baseDatos.getError();
            }
            else this.error = cadenaSQLvacia;

            return numero;
        }
        
        /** Método que ejecuta la consulta SQL recibida como parámetro y devuelve la cantidad de registros que tiene el resultado de la misma. */
        public int contarRegistros(String consultaSQL)
        {
            int cantidad = 0;
            this.error = "";

            if (!consultaSQL.Trim().Equals(""))
            {
                cantidad = this.baseDatos.cantidadRegistros(consultaSQL);
                this.error = this.baseDatos.getError();
            }
            else this.error = cadenaSQLvacia;

            return cantidad;
        }

        /** Método que ejecuta la consulta SQL recibida como parámetro y devuelve el resultado de las mismas en un DataSet. */
        public DataSet obtenerDatos(String consultaSQL)
        {
            DataSet resultadoConsulta = null;
            this.cantResultado = 0;
            this.error = "";

            if (!consultaSQL.Trim().Equals(""))
            {
                resultadoConsulta = this.baseDatos.consultar(consultaSQL);
                this.cantResultado = this.baseDatos.getFilasAfectadas();
                this.error = this.baseDatos.getError();
            }
            else this.error = cadenaSQLvacia;

            return resultadoConsulta;
        }

        /** Método que ejecuta una consultas SQL que se arma dinmámicamente según los parámetros recibidos, y 
         * devuelve el resultado de las mismas en un DataSet. 
         * Recibe como parámetros: 
         * ** nombre de la tabla en la BD que se desea consultar.
         * ** un arreglo de cadenas que representan las columnas de la tabla que se desean consultar,
         * ** un arreglo de cadenas que representan los valores para cada una de las columnas del parámetro anterior y el tipo
         * de búsqueda en cada caso.
         */
        public DataSet obtenerDatos(String nombreTabla, String[] columnasFiltros, String[] valoresFiltros, String[] orden)
        {
            String camposConsulta = consultaCamposDefault;
            return this.obtenerDatos(camposConsulta, nombreTabla, columnasFiltros, valoresFiltros, orden);
        }

        public DataSet obtenerDatos(String camposConsulta, String nombreTabla, String[] tablasJoin, String[] columnasFiltros, String[] valoresFiltros, String[] orden)
        {
            int registroInicial = -1, registroFinal = -1;
            return this.obtenerDatos(camposConsulta, nombreTabla, tablasJoin, columnasFiltros, valoresFiltros, orden, registroInicial, registroFinal);
        }

        public DataSet obtenerDatos(String camposConsulta, String nombreTabla, String[] columnasFiltros, String[] valoresFiltros, String[] orden)
        {
            string[] tablasJoin = new string[] { };
            int registroInicial = -1, registroFinal = -1;
            return this.obtenerDatos(camposConsulta, nombreTabla, tablasJoin, columnasFiltros, valoresFiltros, orden, registroInicial, registroFinal);
        }

        /** Método que ejecuta una consultas SQL que se arma dinmámicamente según los parámetros recibidos, y 
         * devuelve el resultado de las mismas en un DataSet. 
         * Recibe como parámetros: 
         * ** nombre de la tabla en la BD que se desea consultar.
         * ** un arreglo de cadenas que representan las columnas de la tabla que se desean consultar,
         * ** un arreglo de cadenas que representan los valores para cada una de las columnas del parámetro anterior y el tipo
         * de búsqueda en cada caso.
         * ** un numero que indica a partir de qué fila y hasta cuál devolver en la consulta (paginación por ejemplo)
         */
        public DataSet obtenerDatos(String nombreTabla, String[] columnasFiltros, String[] valoresFiltros, String[] orden, int registroInicial, int registroFinal)
        {
            string[] tablasJoin = new string[] { };
            String camposConsulta = consultaCamposDefault;
            return this.obtenerDatos(camposConsulta, nombreTabla, tablasJoin, columnasFiltros, valoresFiltros, orden, registroInicial, registroFinal);
        }

        public DataSet obtenerDatos(String camposConsulta, String nombreTabla, String[] tablasJoin, String[] columnasFiltros, String[] valoresFiltros, string[] orden, int registroInicial, int registroFinal)
        {
            String consultaSQL = "";
            if (!nombreTabla.Trim().Equals("") && columnasFiltros.Length == valoresFiltros.Length)
            {
                if (tablasJoin.Length > 0) consultaSQL = ConsultaSQL.consultaCompleja(camposConsulta, nombreTabla, tablasJoin, columnasFiltros, valoresFiltros, orden, registroInicial, registroFinal);
                else consultaSQL = ConsultaSQL.consultaSimple(camposConsulta, nombreTabla, columnasFiltros, valoresFiltros, orden, registroInicial, registroFinal);
            }

            return this.obtenerDatos(consultaSQL);
        }

        /** Método que ejecuta una sentencia SQL de tipo INSERT, UPDATE o DELETE. No devuelve nada.
         * Para conocer el resultado de la operación se debe consultar el atributo error de la clase.
         * Recibe como parámetros: 
         * ** caracter que indica qué operación se realizará: A: alta, B: baja, M; modificación 
         * ** nombre de la tabla de la BD que se afectará.
         * ** un arreglo de cadenas que representan las columnas de la tabla que se desean insertar o modificar (arreglo vacío en caso de baja),
         * ** un arreglo de cadenas que representan los valores para cada una de las columnas del parámetro anterior y el tipo de búsqueda en cada caso.
         * (arreglo vacío en caso de baja)
         * ** un arreglo de cadenas que representan las columnas de la tabla que se utilizan como filtros (arreglo vacío en caso de altas),
         * ** un arreglo de cadenas que representan los valores para cada uno de los filtros del parámetro anterior (arreglo vacío en caso de baja)
         */
        public void ejecutarABM(char operacion, String nombreTabla, String[] nombresColumnas, String[] valoresCampos, String[] columnasFiltros, String[] valoresFiltros)
        {
            Boolean idAutoGenerado = true;
            this.ejecutarABM(operacion, nombreTabla, nombresColumnas, valoresCampos, columnasFiltros, valoresFiltros, idAutoGenerado);
        }

        public void ejecutarABM(char operacion, String nombreTabla, String[] nombresColumnas, String[] valoresCampos, String[] columnasFiltros, String[] valoresFiltros, Boolean idAutoGenerado)
        {
            String consultaSQL = "";
            this.ultimoIdGenerado = 0;
            this.error = "";

            switch (operacion)
            {
                case TipoOperacionABM.ALTA: consultaSQL = ConsultaSQL.agregarElemento(nombreTabla, nombresColumnas, valoresCampos, idAutoGenerado);
                    break;
                case TipoOperacionABM.BAJA: consultaSQL = ConsultaSQL.eliminarElemento(nombreTabla, columnasFiltros, valoresFiltros);
                    break;
                case TipoOperacionABM.MODIFICACION: consultaSQL = ConsultaSQL.actualizarElemento(nombreTabla, nombresColumnas, valoresCampos, columnasFiltros, valoresFiltros);
                    break;
            }

            if (!consultaSQL.Trim().Equals(""))
            {
                this.baseDatos.ejecutarSQL(consultaSQL);
                this.ultimoIdGenerado = this.baseDatos.getIdGenerado();
                this.error = this.baseDatos.getError();
            }
            else this.error = cadenaSQLvacia;
        }
    }
}